package com.dtp.core.notify.manager;

import com.dtp.common.ApplicationContextHolder;
import com.dtp.common.em.NotifyTypeEnum;
import com.dtp.common.pattern.filter.Filter;
import com.dtp.common.pattern.filter.InvokerChain;
import com.dtp.common.pattern.filter.InvokerChainFactory;
import com.dtp.core.context.BaseNotifyCtx;
import com.dtp.core.notify.filter.AlarmBaseFilter;
import com.dtp.core.notify.filter.NoticeBaseFilter;
import com.dtp.core.notify.filter.NotifyFilter;
import com.dtp.core.notify.invoker.AlarmInvoker;
import com.dtp.core.notify.invoker.NoticeInvoker;
import com.google.common.collect.Lists;
import lombok.val;

import java.util.Collection;
import java.util.Comparator;
import java.util.stream.Collectors;

/**
 * 通知过滤器构建器，构建调用链
 *
 * @author yanhom
 * @since 1.0.0
 *
 * @remark muse
 */
public class NotifyFilterBuilder {

    private NotifyFilterBuilder() { }

    /** 构建警告调用链 */
    public static InvokerChain<BaseNotifyCtx> getAlarmInvokerChain() {
        // 步骤1：获得通知类型符合ALARM（警告通知）的过滤器列表
        val filters = ApplicationContextHolder.getBeansOfType(NotifyFilter.class);
        Collection<NotifyFilter> alarmFilters = Lists.newArrayList(filters.values());
        alarmFilters.add(new AlarmBaseFilter()); // 添加AlarmBaseFilter类型过滤器
        alarmFilters = alarmFilters.stream()
                .filter(x -> x.supports(NotifyTypeEnum.ALARM)) // NotifyTypeEnum包含COMMON（普通通知）和ALARM（警告通知），过滤掉不支持和ALARM通知类型的NotifyFilter
                .sorted(Comparator.comparing(Filter::getOrder)) // 根据getOrder方法进行排序NotifyRedisRateLimiterFilter(10) > AlarmBaseFilter(0) = NoticeBaseFilter(0)
                .collect(Collectors.toList());

        // 步骤2：获得调用链
        return InvokerChainFactory.buildInvokerChain(new AlarmInvoker(), alarmFilters.toArray(new NotifyFilter[0]));
    }

    /** 构建普通通知调用链 */
    public static InvokerChain<BaseNotifyCtx> getCommonInvokerChain() {
        // 获得通知类型符合COMMON（普通通知）的过滤器列表
        val filters = ApplicationContextHolder.getBeansOfType(NotifyFilter.class);
        Collection<NotifyFilter> noticeFilters = Lists.newArrayList(filters.values());
        noticeFilters.add(new NoticeBaseFilter()); // 添加NoticeBaseFilter类型过滤器
        noticeFilters = noticeFilters.stream()
                .filter(x -> x.supports(NotifyTypeEnum.COMMON)) // 过滤掉不支持COMMON通知类型的NotifyFilter
                .sorted(Comparator.comparing(Filter::getOrder))
                .collect(Collectors.toList());

        // 步骤2：获得调用链
        return InvokerChainFactory.buildInvokerChain(new NoticeInvoker(), noticeFilters.toArray(new NotifyFilter[0]));
    }
}
